package com.zyzg.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.zyzg.domain.*;
import com.zyzg.mapper.DataMapper;
import com.zyzg.service.IDataService;
import com.zyzg.utils.AjaxResult;
import com.zyzg.utils.DistanceUtils;
import com.zyzg.utils.redis.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author: lurui
 * @CreateTime: 2021-03-29 11:25
 * @Description: ${Description}
 */
@Slf4j
@Service
public class DataServiceImpl implements IDataService {

    @Autowired
    private DataMapper dataMapper;

    @Autowired
    private RedisCache redisCache;

    private String[] carNames = new String[]{"绿卡", "黄卡", "红卡", "蓝卡"};

    @Override
    public List<NearbyCarInfoVo> getCodeByCarInfo(PeripheryDevParam param) {
        String[] codes = param.getCode().split(",");
        List<NearbyCarInfoVo> list = dataMapper.getCodeByCarInfo(codes);
        Map<String, Integer> cardStates = getCardState(codes);
        Map<String, String> sns = getSns(codes);
        for (NearbyCarInfoVo nearbyCarInfoVo : list) {
            nearbyCarInfoVo.setSn(sns.get(nearbyCarInfoVo.getCode()));
            nearbyCarInfoVo.setCardStatus(cardStates.get(nearbyCarInfoVo.getCode()));
            // 计算距离
            nearbyCarInfoVo.setDist(Math.round(DistanceUtils.calculateDistance(param.getLng(), param.getLat(), nearbyCarInfoVo.getGoogleLongitude(), nearbyCarInfoVo.getGoogleLatitude())/1000.0 * 10.0) / 10.0);
            if (nearbyCarInfoVo.getGpsDateTime().getTime() > new Date().getTime()-5*60*1000) {
                if (nearbyCarInfoVo.getAccState().equals("1")){
                    nearbyCarInfoVo.setWorkState("工作");
                }
                nearbyCarInfoVo.setCarState("在线");
                nearbyCarInfoVo.setWorkIconUrl(nearbyCarInfoVo.getAppWorkingIcon());
                if(nearbyCarInfoVo.getWorkIconUrl()!=null && !nearbyCarInfoVo.getWorkIconUrl().isEmpty())
                {
                    nearbyCarInfoVo.setDefaultIcon(nearbyCarInfoVo.getWorkIconUrl());
                }
            }else {
                nearbyCarInfoVo.setAccState("0");
                nearbyCarInfoVo.setCarState("离线");
                nearbyCarInfoVo.setWorkIconUrl(nearbyCarInfoVo.getAppLoadingIcon());
                if(nearbyCarInfoVo.getLoadingIcon()!=null && !nearbyCarInfoVo.getLoadingIcon().isEmpty())
                {
                    nearbyCarInfoVo.setDefaultIcon(nearbyCarInfoVo.getLoadingIcon());
                }
            }
        }
        return list;
    }

    @Override
    public AjaxResult getResSerialNo(EquipmentSnParam param) {
        if (param.getCode() != null) {
            EquipmentSn ec = dataMapper.getSnByCode(param.getCode());
            EquipmentSn eui = dataMapper.getSnByUidAndEquipmentId(param);
            if (ec == null) {
                if (eui == null) {
                    EquipmentSn equipmentSn = new EquipmentSn();
                    equipmentSn.setSn(getEquipmentSn());
                    equipmentSn.setCode(param.getCode());
                    equipmentSn.setEquipmentId(param.getEquipmentId());
                    equipmentSn.setUid(param.getUid());
                    dataMapper.saveEquipmentSn(equipmentSn);
                    return AjaxResult.success("获取成功",equipmentSn);
                }else {
                    eui.setCode(param.getCode());
                    dataMapper.updateEquipmentSn(eui);
                    return AjaxResult.success("获取成功", eui);
                }
            }else {
                if (ec.getEquipmentId() != null && ec.getUid() != null) {
                    if (ec.getEquipmentId() != ec.getEquipmentId() || ec.getUid() != ec.getUid()) {
                        return AjaxResult.error("环保编号已被绑定");
                    }
                }
                if (eui != null && ec.getCode() != eui.getCode()) {
                    //删除临时过渡数据
                    if (dataMapper.getEquipmentSnById(eui.getId()) != null) {
                        dataMapper.delEquipmentSnById(eui.getId()); //删除临时过渡数据
                    }
                }
                ec.setEquipmentId(param.getEquipmentId());
                ec.setUid(param.getUid());
                dataMapper.updateEquipmentSn(ec);
                return AjaxResult.success("获取成功", ec);
            }
        }else {
            EquipmentSn equipmentSn = new EquipmentSn();
            //生产一个新的sn
            equipmentSn.setSn(getEquipmentSn());
            equipmentSn.setCode(param.getCode());
            equipmentSn.setUid(param.getUid());
            equipmentSn.setEquipmentId(param.getEquipmentId());
            dataMapper.saveEquipmentSn(equipmentSn);
            return AjaxResult.success("获取成功", equipmentSn);
        }
    }

    @Override
    public AjaxResult getIsInstallDev(String code) {
        boolean isinstall = false;
        if (dataMapper.checkIsIntallDev(code) > 0) {
            isinstall = true;
        }
        return AjaxResult.success("成功", isinstall);
    }

    @Override
    public AjaxResult getNearbyCarInfo(RealtimeParam realtimeParam) {
        List<LngLatEntity> lngLatEntities = new ArrayList<>();
        String rediskey = "nearbyCarInfo:" + realtimeParam.getLng() + realtimeParam.getLat() + ":" + realtimeParam.getRadius();
        // KEY是否存在
        if (redisCache.hasKey(rediskey)) {
            lngLatEntities = redisCache.getCacheObject(rediskey);
        } else {
            try {
                lngLatEntities = dataMapper.selectNealrylnglat(realtimeParam.getLng(), realtimeParam.getLat(), realtimeParam.getRadius());
                lngLatEntities = lngLatEntities.stream().sorted(Comparator.comparing(LngLatEntity::getDist)).collect(Collectors.toList());
                redisCache.setCacheObject(rediskey, lngLatEntities, 300, TimeUnit.SECONDS);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (lngLatEntities == null || lngLatEntities.isEmpty()) {
            return AjaxResult.error("未查询到数据");
        }

        JSONObject result = new JSONObject();

        //计算分页起始和结束的索引
        int start_index = (realtimeParam.getPage() - 1) * realtimeParam.getPageSize();

        List<LngLatEntity> lnglatVosgetpage = lngLatEntities.stream().skip(start_index).limit(realtimeParam.getPageSize()).collect(Collectors.toList());
        result.put("current",realtimeParam.getPage());
        result.put("total",lngLatEntities.size());
        result.put("pages",lngLatEntities.size() / realtimeParam.getPageSize() + 1);

        List<String> configIds = new ArrayList<>();
        for (int i = 0; i < lnglatVosgetpage.size(); i++) {
            configIds.add(lnglatVosgetpage.get(i).getConfigId());
        }
        List<NearbyCarListVo> nearbyCarListVoList = dataMapper.selectNealryByConfigId(configIds, realtimeParam.getDvcId(),realtimeParam.getBrandId(),realtimeParam.getModelId());

        String[] codes = nearbyCarListVoList.stream().map(NearbyCarListVo::getCode).toArray(String[]::new);
        Map<String, Integer> cardStates = getCardState(codes);
        Map<String, String> sns = getSns(codes);
        for (NearbyCarListVo nearbyCarListVo : nearbyCarListVoList) {
            LngLatEntity lnglatVo = lngLatEntities.stream().filter(c -> c.getTerminalCode().equals(nearbyCarListVo.getDeviceNumber())).findFirst().orElse(null);
            if (lnglatVo != null) {
                nearbyCarListVo.setDist(Math.round(((int) lnglatVo.getDist()) / 1000.0 * 10.0) / 10.0);
            }
            int carstatusindex = nearbyCarListVo.getCardStatus();
            if (carstatusindex > 0) {
                carstatusindex = carstatusindex - 1;
            }
            nearbyCarListVo.setCardName(carNames[carstatusindex]);

            nearbyCarListVo.setSn(sns.get(nearbyCarListVo.getCode()));
            nearbyCarListVo.setCardStatus(cardStates.get(nearbyCarListVo.getCode()));
            if (nearbyCarListVo.getGpsDateTime().getTime() > new Date().getTime()-5*60*1000) {
                if (nearbyCarListVo.getAccState().equals("1")){
                    nearbyCarListVo.setWorkState("工作");
                }
                nearbyCarListVo.setCarState("在线");
                nearbyCarListVo.setWorkIconUrl(nearbyCarListVo.getAppWorkingIcon());
                if(nearbyCarListVo.getWorkIconUrl()!=null && !nearbyCarListVo.getWorkIconUrl().isEmpty())
                {
                    nearbyCarListVo.setDefaultIcon(nearbyCarListVo.getWorkIconUrl());
                }
            }else {
                nearbyCarListVo.setAccState("0");
                nearbyCarListVo.setCarState("离线");
                nearbyCarListVo.setWorkIconUrl(nearbyCarListVo.getAppLoadingIcon());
                if(nearbyCarListVo.getLoadingIcon()!=null && !nearbyCarListVo.getLoadingIcon().isEmpty())
                {
                    nearbyCarListVo.setDefaultIcon(nearbyCarListVo.getLoadingIcon());
                }
            }
        }
        nearbyCarListVoList= nearbyCarListVoList.stream().sorted(Comparator.comparing(NearbyCarListVo::getDist)).collect(Collectors.toList());
        result.put("records", nearbyCarListVoList);
        return AjaxResult.success(result);
    }

    /**
     * 获取设备自编号
     */
    private String getEquipmentSn() {
        String SearchSn = dataMapper.SeachEquipmentSn();
        if (SearchSn == null) {
            return SearchSn = "YJ000001";
        } else {
            Integer maxsn = Integer.parseInt(SearchSn.substring(2))+1;
            SearchSn = "YJ" + String.format("%06d", maxsn);
            return SearchSn;
        }
    }

    private Map<String, Integer> getCardState(String[] codes) {
        Map<String, Integer> cardStatusMap = new HashMap<>();
        for (JSONObject row : dataMapper.getCardStates(codes)) {
            cardStatusMap.put(row.getString("code"), row.getInteger("card_status"));
        }
        return cardStatusMap;
    }

    private Map<String, String> getSns(String[] codes) {
        Map<String, String> snMap = new HashMap<>();
        for (JSONObject row : dataMapper.getSns(codes)) {
            snMap.put(row.getString("code"), row.getString("sn"));
        }
        return snMap;
    }


}
